package org.codert.wxpay.config;


import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.apache.http.client.HttpClient;
import org.codert.wxpay.support.ConstantEnum;
import org.codert.wxpay.support.properties.WxPayProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.util.Objects;

/**
 * @author: TanJingyu
 * @create: 2021-08-12 15:18
 **/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(WechatPayHttpClientBuilder.class)
public class HttpClientConfiguration {
    private final WxPayProperties properties;

    public HttpClientConfiguration(WxPayProperties wxPayProperties) {
        this.properties = wxPayProperties;
    }

    @Bean
    @ConditionalOnMissingBean(name = "wxPayHttpClient")
    public HttpClient wxPayHttpClient() throws FileNotFoundException {
        WxPayProperties.Identification identification = properties.getIdentification();

        PrivateKey merchantPrivateKey = generatePrivateKey(identification);
        String merchantId = identification.getMerchantId();
        String merchantSerialNumber = identification.getMerchantSerialNumber();
        String apiV3Key = identification.getApiV3Key();

        AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
                new WechatPay2Credentials(merchantId, new PrivateKeySigner(merchantSerialNumber, merchantPrivateKey)),
                apiV3Key.getBytes(StandardCharsets.UTF_8));

        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey)
                .withValidator(new WechatPay2Validator(verifier));

        // todo 读取配置文件，自定义更多配置
//        builder.

        return builder.build();
    }

    /**
     * 加载商户api私钥
     * WxPayProperties中配置私钥文件存储位置
     * 1.默认存储为在文件
     * 2.密钥存储为字符串
     * @throws FileNotFoundException
     */
    private PrivateKey generatePrivateKey(WxPayProperties.Identification identification) throws FileNotFoundException {
        Objects.requireNonNull(identification, "未配置微信支付相关必要信息: WxPayProperties.Identification");
        Objects.requireNonNull(identification.getPrivateKey(), "未配置微信支付私钥信息: WxPayProperties.Identification.PrivateKey");
        Objects.requireNonNull(identification.getPrivateKey().getValue(), "未配置微信支付私钥信息: WxPayProperties.Identification.PrivateKey");

        WxPayProperties.Identification.PrivateKey wxPrivateKey = identification.getPrivateKey();

        PrivateKey privateKey;

        try {
            if (wxPrivateKey.getType() == ConstantEnum.STRING) {
                privateKey = PemUtil.loadPrivateKey(
                        new ByteArrayInputStream(wxPrivateKey.getValue().getBytes(StandardCharsets.UTF_8)));
            }else {
                privateKey = PemUtil.loadPrivateKey(
                        new FileInputStream(wxPrivateKey.getValue()));
            }
            return privateKey;
        } catch (FileNotFoundException e) {
            throw new FileNotFoundException("加载私钥文件失败，文件路径： " + wxPrivateKey.getValue());
        }
    }
}
